mercurial/branchmap.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Mon, 04 Mar 2024 04:16:15 +0100
branchstable
changeset 51447 40943970b7ae
parent 51375 02e7d79edf62
child 51508 0239ebdd0740
permissions -rw-r--r--
config: move the option to mmap rev branch cache in the storage section See previous commit for rational.
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
#
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 46794
diff changeset
     3
# Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
18116
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
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
import struct
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
from .node import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
    bin,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
    hex,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
    nullrev,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    15
)
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    16
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    17
from typing import (
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    18
    Callable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    19
    Dict,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    20
    Iterable,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    21
    List,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    22
    Optional,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    23
    Set,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    24
    TYPE_CHECKING,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    25
    Tuple,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    26
    Union,
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    27
)
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    28
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    29
from . import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    30
    encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
    31
    error,
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
    32
    obsolete,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    33
    scmutil,
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
    34
    util,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    35
)
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    36
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    37
from .utils import (
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
    38
    repoviewutil,
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    39
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    40
)
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    41
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    42
if TYPE_CHECKING:
46794
e2f7b2695ba1 merge with stable
Matt Harbison <matt_harbison@yahoo.com>
parents: 46780 46685
diff changeset
    43
    from . import localrepo
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
    44
51285
9d3721552b6c pytype: import typing directly
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 49300
diff changeset
    45
    assert [localrepo]
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
    46
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
    47
subsettable = repoviewutil.subsettable
42138
caebe5e7f4bd repoview: move subsettable in a dedicated module
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42134
diff changeset
    48
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    49
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
    50
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
    51
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
    52
18118
e70ff1e599f4 branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18117
diff changeset
    53
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
    54
class BranchMapCache:
41718
a87ca1d7e61d branchmap: improve doc about BranchMapCache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41678
diff changeset
    55
    """mapping of filtered views of repo with their branchcache"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
    56
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    57
    def __init__(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    58
        self._per_filter = {}
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
    59
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    60
    def __getitem__(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    61
        self.updatecache(repo)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    62
        return self._per_filter[repo.filtername]
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    63
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    64
    def updatecache(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    65
        """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
    66
        # 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
    67
        # 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
    68
        # is stale.
18121
f8a13f061a8a branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18120
diff changeset
    69
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    70
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    71
        filtername = repo.filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    72
        bcache = self._per_filter.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    73
        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
    74
            # 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
    75
            bcache = branchcache.fromfile(repo)
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
    76
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    77
        revs = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    78
        if bcache is None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    79
            # 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
    80
            # 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
    81
            # revisions.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    82
            subsetname = subsettable.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    83
            if subsetname is not None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    84
                subset = repo.filtered(subsetname)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    85
                bcache = self[subset].copy()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    86
                extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    87
                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
    88
            else:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    89
                # nothing to fall back on, start empty.
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
    90
                bcache = branchcache(repo)
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
    91
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    92
        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
    93
        if revs:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    94
            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
    95
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    96
        assert bcache.validfor(repo), filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    97
        self._per_filter[repo.filtername] = bcache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    98
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    99
    def replace(self, repo, remotebranchmap):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   100
        """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
   101
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   102
        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
   103
        remote.
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   104
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   105
        """
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   106
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   107
        clrev = cl.rev
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   108
        clbranchinfo = cl.branchinfo
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   109
        rbheads = []
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
   110
        closed = set()
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   111
        for bheads in remotebranchmap.values():
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   112
            rbheads += bheads
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   113
            for h in bheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   114
                r = clrev(h)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   115
                b, c = clbranchinfo(r)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   116
                if c:
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
   117
                    closed.add(h)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   118
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   119
        if rbheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   120
            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
   121
            cache = branchcache(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   122
                repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   123
                remotebranchmap,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   124
                repo[rtiprev].node(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   125
                rtiprev,
43688
5cdc3c1292f6 branchmap: make "closed" a set from beginning instead of converting from list
Martin von Zweigbergk <martinvonz@google.com>
parents: 43636
diff changeset
   126
                closednodes=closed,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   127
            )
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   128
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   129
            # 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
   130
            # filter above served are unlikely to be fetch from a clone
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   131
            for candidate in (b'base', b'immutable', b'served'):
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   132
                rview = repo.filtered(candidate)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   133
                if cache.validfor(rview):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   134
                    self._per_filter[candidate] = cache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   135
                    cache.write(rview)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   136
                    return
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   137
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   138
    def clear(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   139
        self._per_filter.clear()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   140
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   141
    def write_delayed(self, repo):
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   142
        unfi = repo.unfiltered()
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   143
        for filtername, cache in self._per_filter.items():
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   144
            if cache._delayed:
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   145
                repo = unfi.filtered(filtername)
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   146
                cache.write(repo)
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   147
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   148
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   149
def _unknownnode(node):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   150
    """raises ValueError when branchcache found a node which does not exists"""
49300
227124098e14 py3: use `x.hex()` instead of `pycompat.sysstr(node.hex(x))`
Manuel Jacob <me@manueljacob.de>
parents: 49203
diff changeset
   151
    raise ValueError('node %s does not exist' % node.hex())
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   152
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   153
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   154
def _branchcachedesc(repo):
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   155
    if repo.filtername is not None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   156
        return b'branch cache (%s)' % repo.filtername
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   157
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   158
        return b'branch cache'
42602
c7d236b55a3e py3: fix formatting of branchmap log messages with repo.filtername=None
Martin von Zweigbergk <martinvonz@google.com>
parents: 42214
diff changeset
   159
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   160
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
   161
class branchcache:
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   162
    """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
   163
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   164
    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
   165
    branch heads of a repo.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   166
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   167
    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
   168
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   169
    <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
   170
    <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
   171
    <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
   172
    ...
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   173
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   174
    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
   175
    branch cache is for a filtered repo view, an optional third hash is
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   176
    included that hashes the hashes of all filtered and obsolete revisions.
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   177
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   178
    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
   179
    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
   180
    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
   181
    """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   182
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   183
    def __init__(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   184
        self,
51287
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   185
        repo: "localrepo.localrepository",
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   186
        entries: Union[
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   187
            Dict[bytes, List[bytes]], Iterable[Tuple[bytes, List[bytes]]]
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   188
        ] = (),
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   189
        tipnode: Optional[bytes] = None,
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   190
        tiprev: Optional[int] = nullrev,
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   191
        filteredhash: Optional[bytes] = None,
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   192
        closednodes: Optional[Set[bytes]] = None,
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   193
        hasnode: Optional[Callable[[bytes], bool]] = None,
f15cb5111a1e pytype: move some type comment to proper annotation
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51285
diff changeset
   194
    ) -> None:
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   195
        """hasnode is a function which can be used to verify whether changelog
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   196
        has a given node or not. If it's not provided, we assume that every node
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   197
        we have exists in changelog"""
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   198
        self._repo = repo
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   199
        self._delayed = False
47012
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   200
        if tipnode is None:
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   201
            self.tipnode = repo.nullid
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   202
        else:
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   203
            self.tipnode = tipnode
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   204
        self.tiprev = tiprev
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   205
        self.filteredhash = filteredhash
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   206
        # 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
   207
        # 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
   208
        # heads.
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   209
        if closednodes is None:
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   210
            self._closednodes = set()
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   211
        else:
43636
9c1eccdd7ed8 branchmap: annotate constructor type for branchcache
Augie Fackler <augie@google.com>
parents: 43634
diff changeset
   212
            self._closednodes = closednodes
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   213
        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
   214
        # 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
   215
        self._closedverified = False
111de135fc76 branchcache: add attributes to track which nodes are verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42005
diff changeset
   216
        # 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
   217
        self._verifiedbranches = set()
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   218
        self._hasnode = hasnode
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   219
        if self._hasnode is None:
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   220
            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
   221
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   222
    def _verifyclosed(self):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   223
        """verify the closed nodes we have"""
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   224
        if self._closedverified:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   225
            return
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   226
        for node in self._closednodes:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   227
            if not self._hasnode(node):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   228
                _unknownnode(node)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   229
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   230
        self._closedverified = True
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   231
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   232
    def _verifybranch(self, branch):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   233
        """verify head nodes for the given branch."""
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   234
        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
   235
            return
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   236
        for n in self._entries[branch]:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   237
            if not self._hasnode(n):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   238
                _unknownnode(n)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   239
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   240
        self._verifiedbranches.add(branch)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   241
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   242
    def _verifyall(self):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   243
        """verifies nodes of all the branches"""
42133
75e8e16ca107 branchcache: only iterate over branches which needs to be verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42132
diff changeset
   244
        needverification = set(self._entries.keys()) - self._verifiedbranches
75e8e16ca107 branchcache: only iterate over branches which needs to be verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42132
diff changeset
   245
        for b in needverification:
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   246
            self._verifybranch(b)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   247
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   248
    def __iter__(self):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   249
        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
   250
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   251
    def __setitem__(self, key, value):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   252
        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
   253
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   254
    def __getitem__(self, key):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   255
        self._verifybranch(key)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   256
        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
   257
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   258
    def __contains__(self, key):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   259
        self._verifybranch(key)
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   260
        return key in self._entries
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   261
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   262
    def iteritems(self):
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   263
        for k, v in self._entries.items():
42134
f0203c3406e7 branchcache: lazily validate nodes in iteritems()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42133
diff changeset
   264
            self._verifybranch(k)
f0203c3406e7 branchcache: lazily validate nodes in iteritems()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42133
diff changeset
   265
            yield k, v
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   266
42603
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   267
    items = iteritems
3018749a71bb py3: source-transform only call-sites of iteritems(), not definitions
Martin von Zweigbergk <martinvonz@google.com>
parents: 42602
diff changeset
   268
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   269
    def hasbranch(self, label):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   270
        """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
   271
        self._verifybranch(label)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   272
        return label in self._entries
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   273
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   274
    @classmethod
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   275
    def fromfile(cls, repo):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   276
        f = None
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   277
        try:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   278
            f = repo.cachevfs(cls._filename(repo))
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   279
            lineiter = iter(f)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   280
            cachekey = next(lineiter).rstrip(b'\n').split(b" ", 2)
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   281
            last, lrev = cachekey[:2]
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   282
            last, lrev = bin(last), int(lrev)
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   283
            filteredhash = None
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   284
            hasnode = repo.changelog.hasnode
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   285
            if len(cachekey) > 2:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   286
                filteredhash = bin(cachekey[2])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   287
            bcache = cls(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   288
                repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   289
                tipnode=last,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   290
                tiprev=lrev,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   291
                filteredhash=filteredhash,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   292
                hasnode=hasnode,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   293
            )
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   294
            if not bcache.validfor(repo):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   295
                # invalidate the cache
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43499
diff changeset
   296
                raise ValueError('tip differs')
41808
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   297
            bcache.load(repo, lineiter)
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   298
        except (IOError, OSError):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   299
            return None
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   300
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   301
        except Exception as inst:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   302
            if repo.ui.debugflag:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   303
                msg = b'invalid %s: %s\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   304
                repo.ui.debug(
43499
1a47fe4bc154 branchmap: pytype is confused about bytestr
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   305
                    msg
1a47fe4bc154 branchmap: pytype is confused about bytestr
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   306
                    % (
1a47fe4bc154 branchmap: pytype is confused about bytestr
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   307
                        _branchcachedesc(repo),
46685
799973a44c82 branchmap: force Exception to bytes before logging
Matt Harbison <matt_harbison@yahoo.com>
parents: 46254
diff changeset
   308
                        stringutil.forcebytestr(inst),
43499
1a47fe4bc154 branchmap: pytype is confused about bytestr
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
   309
                    )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   310
                )
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   311
            bcache = None
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   312
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   313
        finally:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   314
            if f:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   315
                f.close()
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   316
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   317
        return bcache
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   318
41808
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   319
    def load(self, repo, lineiter):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   320
        """fully loads the branchcache by reading from the file using the line
41808
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   321
        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
   322
        for line in lineiter:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   323
            line = line.rstrip(b'\n')
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
   324
            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
   325
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   326
            node, state, label = line.split(b" ", 2)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   327
            if state not in b'oc':
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43499
diff changeset
   328
                raise ValueError('invalid branch state')
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
   329
            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
   330
            node = bin(node)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   331
            self._entries.setdefault(label, []).append(node)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   332
            if state == b'c':
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
   333
                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
   334
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   335
    @staticmethod
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   336
    def _filename(repo):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   337
        """name of a branchcache file for a given repo or repoview"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   338
        filename = b"branch2"
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   339
        if repo.filtername:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   340
            filename = b'%s-%s' % (filename, repo.filtername)
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   341
        return filename
18124
79db6d40bced branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18121
diff changeset
   342
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   343
    def validfor(self, repo):
48719
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   344
        """check that cache contents are valid for (a subset of) this repo
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   345
48719
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   346
        - False when the order of changesets changed or if we detect a strip.
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   347
        - True when cache is up-to-date for the current repo or its subset."""
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   348
        try:
48719
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   349
            node = repo.changelog.node(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
   350
        except IndexError:
48719
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   351
            # changesets were stripped and now we don't even have enough to
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   352
            # find tiprev
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   353
            return False
48719
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   354
        if self.tipnode != node:
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   355
            # tiprev doesn't correspond to tipnode: repo was stripped, or this
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   356
            # repo has a different order of changesets
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   357
            return False
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   358
        tiphash = scmutil.filteredhash(repo, self.tiprev, needobsolete=True)
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   359
        # hashes don't match if this repo view has a different set of filtered
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   360
        # revisions (e.g. due to phase changes) or obsolete revisions (e.g.
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   361
        # history was rewritten)
02e9ad08999b branchmap: split a long condition in branchcache.validfor(), add comments
Anton Shestakov <av6@dwimlabs.net>
parents: 48718
diff changeset
   362
        return self.filteredhash == tiphash
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   363
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   364
    def _branchtip(self, heads):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   365
        """Return tuple with last open head in heads and false,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   366
        otherwise return last closed head and true."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   367
        tip = heads[-1]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   368
        closed = True
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   369
        for h in reversed(heads):
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   370
            if h not in self._closednodes:
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   371
                tip = h
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   372
                closed = False
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   373
                break
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   374
        return tip, closed
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   375
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   376
    def branchtip(self, branch):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   377
        """Return the tipmost open head on branch head, otherwise return the
20245
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   378
        tipmost closed head on branch.
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 44452
diff changeset
   379
        Raise KeyError for unknown branch."""
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   380
        return self._branchtip(self[branch])[0]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   381
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   382
    def iteropen(self, nodes):
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   383
        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
   384
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   385
    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
   386
        self._verifybranch(branch)
42112
29c22496dd97 branchmap: prevent using __getitem__() in branchheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42111
diff changeset
   387
        heads = self._entries[branch]
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   388
        if not closed:
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   389
            heads = list(self.iteropen(heads))
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   390
        return heads
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   391
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   392
    def iterbranches(self):
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   393
        for bn, heads in self.items():
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   394
            yield (bn, heads) + self._branchtip(heads)
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   395
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   396
    def iterheads(self):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   397
        """returns all the heads"""
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   398
        self._verifyall()
48935
2cce2fa5bcf7 py3: replace pycompat.itervalues(x) with x.values()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48913
diff changeset
   399
        return self._entries.values()
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   400
18232
dd0b636b0b65 branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18218
diff changeset
   401
    def copy(self):
dd0b636b0b65 branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18218
diff changeset
   402
        """return an deep copy of the branchcache object"""
42111
f0fa0fc4900a branchmap: dynamically resolve type of branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42007
diff changeset
   403
        return type(self)(
46780
6266d19556ad node: introduce nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46372
diff changeset
   404
            self._repo,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   405
            self._entries,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   406
            self.tipnode,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   407
            self.tiprev,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   408
            self.filteredhash,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   409
            self._closednodes,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   410
        )
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   411
18128
f0d56efaa35a branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18127
diff changeset
   412
    def write(self, repo):
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   413
        tr = repo.currenttransaction()
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   414
        if not getattr(tr, 'finalized', True):
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   415
            # Avoid premature writing.
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   416
            #
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   417
            # (The cache warming setup by localrepo will update the file later.)
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   418
            self._delayed = True
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   419
            return
18128
f0d56efaa35a branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18127
diff changeset
   420
        try:
49203
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   421
            filename = self._filename(repo)
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   422
            with repo.cachevfs(filename, b"w", atomictemp=True) as f:
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   423
                cachekey = [hex(self.tipnode), b'%d' % self.tiprev]
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   424
                if self.filteredhash is not None:
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   425
                    cachekey.append(hex(self.filteredhash))
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   426
                f.write(b" ".join(cachekey) + b'\n')
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   427
                nodecount = 0
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   428
                for label, nodes in sorted(self._entries.items()):
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   429
                    label = encoding.fromlocal(label)
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   430
                    for node in nodes:
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   431
                        nodecount += 1
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   432
                        if node in self._closednodes:
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   433
                            state = b'c'
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   434
                        else:
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   435
                            state = b'o'
f923bdd7477d branchmap: use a context manager when writing the branchmap
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
   436
                        f.write(b"%s %s %s\n" % (hex(node), state, label))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   437
            repo.ui.log(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   438
                b'branchcache',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   439
                b'wrote %s with %d labels and %d nodes\n',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   440
                _branchcachedesc(repo),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   441
                len(self._entries),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   442
                nodecount,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   443
            )
48677
8e5effbf52d0 branchmap: stop writing cache for uncommitted data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47128
diff changeset
   444
            self._delayed = False
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
   445
        except (IOError, OSError, error.Abort) as inst:
34370
d0db41af73c0 branchmap: remove superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34074
diff changeset
   446
            # Abort may be raised by read only opener, so log and continue
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   447
            repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   448
                b"couldn't write branch cache: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   449
                % stringutil.forcebytestr(inst)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   450
            )
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   451
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
   452
    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
   453
        """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
   454
        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
   455
        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
   456
        """
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   457
        starttime = util.timer()
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   458
        cl = repo.changelog
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   459
        # collect new branch entries
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   460
        newbranches = {}
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   461
        getbranchinfo = repo.revbranchcache().branchinfo
18307
0eed2546118a branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18305
diff changeset
   462
        for r in revgen:
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   463
            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
   464
            newbranches.setdefault(branch, []).append(r)
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   465
            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
   466
                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
   467
42214
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   468
        # new tip revision which we found after iterating items from new
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   469
        # branches
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   470
        ntiprev = self.tiprev
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   471
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   472
        # Delay fetching the topological heads until they are needed.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   473
        # A repository without non-continous branches can skip this part.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   474
        topoheads = None
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   475
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   476
        # If a changeset is visible, its parents must be visible too, so
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   477
        # use the faster unfiltered parent accessor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   478
        parentrevs = repo.unfiltered().changelog.parentrevs
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   479
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   480
        # Faster than using ctx.obsolete()
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   481
        obsrevs = obsolete.getrevs(repo, b'obsolete')
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   482
48913
f254fc73d956 global: bulk replace simple pycompat.iteritems(x) with x.items()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   483
        for branch, newheadrevs in newbranches.items():
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   484
            # For every branch, compute the new branchheads.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   485
            # A branchhead is a revision such that no descendant is on
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   486
            # the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   487
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   488
            # The branchheads are computed iteratively in revision order.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   489
            # This ensures topological order, i.e. parents are processed
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   490
            # before their children. Ancestors are inclusive here, i.e.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   491
            # any revision is an ancestor of itself.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   492
            #
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   493
            # Core observations:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   494
            # - The current revision is always a branchhead for the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   495
            #   repository up to that point.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   496
            # - It is the first revision of the branch if and only if
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   497
            #   there was no branchhead before. In that case, it is the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   498
            #   only branchhead as there are no possible ancestors on
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   499
            #   the same branch.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   500
            # - If a parent is on the same branch, a branchhead can
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   501
            #   only be an ancestor of that parent, if it is parent
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   502
            #   itself. Otherwise it would have been removed as ancestor
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   503
            #   of that parent before.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   504
            # - Therefore, if all parents are on the same branch, they
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   505
            #   can just be removed from the branchhead set.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   506
            # - If one parent is on the same branch and the other is not
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   507
            #   and there was exactly one branchhead known, the existing
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   508
            #   branchhead can only be an ancestor if it is the parent.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   509
            #   Otherwise it would have been removed as ancestor of
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   510
            #   the parent before. The other parent therefore can't have
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   511
            #   a branchhead as ancestor.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   512
            # - In all other cases, the parents on different branches
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   513
            #   could have a branchhead as ancestor. Those parents are
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   514
            #   kept in the "uncertain" set. If all branchheads are also
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   515
            #   topological heads, they can't have descendants and further
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   516
            #   checks can be skipped. Otherwise, the ancestors of the
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   517
            #   "uncertain" set are removed from branchheads.
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   518
            #   This computation is heavy and avoided if at all possible.
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   519
            bheads = self._entries.get(branch, [])
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44306
diff changeset
   520
            bheadset = {cl.rev(node) for node in bheads}
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   521
            uncertain = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   522
            for newrev in sorted(newheadrevs):
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   523
                if newrev in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   524
                    # We ignore obsolete changesets as they shouldn't be
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   525
                    # considered heads.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   526
                    continue
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   527
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   528
                if not bheadset:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   529
                    bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   530
                    continue
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   531
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   532
                parents = [p for p in parentrevs(newrev) if p != nullrev]
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   533
                samebranch = set()
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   534
                otherbranch = set()
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   535
                obsparents = set()
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   536
                for p in parents:
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   537
                    if p in obsrevs:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   538
                        # We ignored this obsolete changeset earlier, but now
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   539
                        # that it has non-ignored children, we need to make
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   540
                        # sure their ancestors are not considered heads. To
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   541
                        # achieve that, we will simply treat this obsolete
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   542
                        # changeset as a parent from other branch.
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   543
                        obsparents.add(p)
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   544
                    elif p in bheadset or getbranchinfo(p)[0] == branch:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   545
                        samebranch.add(p)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   546
                    else:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   547
                        otherbranch.add(p)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   548
                if not (len(bheadset) == len(samebranch) == 1):
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   549
                    uncertain.update(otherbranch)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   550
                    uncertain.update(obsparents)
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   551
                bheadset.difference_update(samebranch)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   552
                bheadset.add(newrev)
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   553
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   554
            if uncertain:
46254
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   555
                if topoheads is None:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   556
                    topoheads = set(cl.headrevs())
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   557
                if bheadset - topoheads:
c4b792fa109e branchmap: avoid ancestor computations in absence of non-continous branches
Joerg Sonnenberger <joerg@bec.de>
parents: 45942
diff changeset
   558
                    floorrev = min(bheadset)
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   559
                    if floorrev <= max(uncertain):
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   560
                        ancestors = set(cl.ancestors(uncertain, floorrev))
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   561
                        bheadset -= ancestors
48718
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   562
            if bheadset:
8b393f40a5e6 branchmap: don't add branch entries if there are no heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48687
diff changeset
   563
                self[branch] = [cl.node(rev) for rev in sorted(bheadset)]
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   564
            tiprev = max(newheadrevs)
42214
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   565
            if tiprev > ntiprev:
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   566
                ntiprev = tiprev
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   567
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   568
        if ntiprev > self.tiprev:
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   569
            self.tiprev = ntiprev
9893d7aa7420 branchcache: store the maximum tip in a variable inside for loop
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42190
diff changeset
   570
            self.tipnode = cl.node(ntiprev)
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   571
19838
23386881abeb branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19837
diff changeset
   572
        if not self.validfor(repo):
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   573
            # old cache key is now invalid for the repo, but we've just updated
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   574
            # the cache and we assume it's valid, so let's make the cache key
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   575
            # valid as well by recomputing it from the cached data
47012
d55b71393907 node: replace nullid and friends with nodeconstants class
Joerg Sonnenberger <joerg@bec.de>
parents: 46819
diff changeset
   576
            self.tipnode = repo.nullid
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   577
            self.tiprev = nullrev
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   578
            for heads in self.iterheads():
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   579
                if not heads:
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   580
                    # all revisions on a branch are obsolete
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   581
                    continue
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   582
                # note: tiprev is not necessarily the tip revision of repo,
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   583
                # because the tip could be obsolete (i.e. not a head)
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   584
                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
   585
                if tiprev > self.tiprev:
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   586
                    self.tipnode = cl.node(tiprev)
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   587
                    self.tiprev = tiprev
48687
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   588
        self.filteredhash = scmutil.filteredhash(
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   589
            repo, self.tiprev, needobsolete=True
f8f2ecdde4b5 branchmap: skip obsolete revisions while computing heads
Anton Shestakov <av6@dwimlabs.net>
parents: 48677
diff changeset
   590
        )
21031
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   591
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   592
        duration = util.timer() - starttime
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   593
        repo.ui.log(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   594
            b'branchcache',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   595
            b'updated %s in %.4f seconds\n',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   596
            _branchcachedesc(repo),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   597
            duration,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   598
        )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   599
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   600
        self.write(repo)
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   601
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   602
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   603
class remotebranchcache(branchcache):
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   604
    """Branchmap info for a remote connection, should not write locally"""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   605
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   606
    def write(self, repo):
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   607
        pass
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   608
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   609
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   610
# Revision branch info cache
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   611
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   612
_rbcversion = b'-v1'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   613
_rbcnames = b'rbc-names' + _rbcversion
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   614
_rbcrevs = b'rbc-revs' + _rbcversion
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   615
# [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   616
_rbcrecfmt = b'>4sI'
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   617
_rbcrecsize = calcsize(_rbcrecfmt)
46360
1726a53a8494 reverse-branch-cache: switch to doubling allocating scheme
Joerg Sonnenberger <joerg@bec.de>
parents: 46254
diff changeset
   618
_rbcmininc = 64 * _rbcrecsize
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   619
_rbcnodelen = 4
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   620
_rbcbranchidxmask = 0x7FFFFFFF
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   621
_rbccloseflag = 0x80000000
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   622
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   623
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   624
class rbcrevs:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   625
    """a byte string consisting of an immutable prefix followed by a mutable suffix"""
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   626
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   627
    def __init__(self, revs):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   628
        self._prefix = revs
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   629
        self._rest = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   630
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   631
    def __len__(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   632
        return len(self._prefix) + len(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   633
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   634
    def unpack_record(self, rbcrevidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   635
        if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   636
            return unpack_from(_rbcrecfmt, util.buffer(self._prefix), rbcrevidx)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   637
        else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   638
            return unpack_from(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   639
                _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   640
                util.buffer(self._rest),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   641
                rbcrevidx - len(self._prefix),
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   642
            )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   643
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   644
    def make_mutable(self):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   645
        if len(self._prefix) > 0:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   646
            entirety = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   647
            entirety[:] = self._prefix
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   648
            entirety.extend(self._rest)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   649
            self._rest = entirety
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   650
            self._prefix = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   651
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   652
    def truncate(self, pos):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   653
        self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   654
        del self._rest[pos:]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   655
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   656
    def pack_into(self, rbcrevidx, node, branchidx):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   657
        if rbcrevidx < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   658
            self.make_mutable()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   659
        buf = self._rest
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   660
        start_offset = rbcrevidx - len(self._prefix)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   661
        end_offset = start_offset + _rbcrecsize
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   662
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   663
        if len(self._rest) < end_offset:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   664
            # bytearray doesn't allocate extra space at least in Python 3.7.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   665
            # When multiple changesets are added in a row, precise resize would
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   666
            # result in quadratic complexity. Overallocate to compensate by
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   667
            # using the classic doubling technique for dynamic arrays instead.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   668
            # If there was a gap in the map before, less space will be reserved.
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   669
            self._rest.extend(b'\0' * end_offset)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   670
        return pack_into(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   671
            _rbcrecfmt,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   672
            buf,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   673
            start_offset,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   674
            node,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   675
            branchidx,
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   676
        )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   677
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   678
    def extend(self, extension):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   679
        return self._rest.extend(extension)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   680
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   681
    def slice(self, begin, end):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   682
        if begin < len(self._prefix):
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   683
            acc = bytearray()
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   684
            acc[:] = self._prefix[begin:end]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   685
            acc.extend(
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   686
                self._rest[begin - len(self._prefix) : end - len(self._prefix)]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   687
            )
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   688
            return acc
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   689
        return self._rest[begin - len(self._prefix) : end - len(self._prefix)]
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   690
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   691
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48935
diff changeset
   692
class revbranchcache:
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   693
    """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
   694
    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
   695
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   696
    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
   697
    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
   698
    thus have a unique index.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   699
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   700
    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
   701
    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
   702
    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
   703
    modification is detected.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   704
    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
   705
    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
   706
    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
   707
    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
   708
    node hashes.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   709
    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
   710
    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
   711
    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
   712
    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
   713
    """
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   714
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   715
    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
   716
        assert repo.filtername is None
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
   717
        self._repo = repo
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   718
        self._names = []  # branch names in local encoding with static index
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   719
        self._rbcrevs = rbcrevs(bytearray())
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   720
        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
   721
        try:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   722
            bndata = repo.cachevfs.read(_rbcnames)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   723
            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
   724
            if bndata:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   725
                self._names = [
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   726
                    encoding.tolocal(bn) for bn in bndata.split(b'\0')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   727
                ]
29423
d2c6f3a948fa branchmap: remove unused exception variable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28558
diff changeset
   728
        except (IOError, OSError):
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   729
            if readonly:
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   730
                # 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
   731
                self.branchinfo = self._branchinfo
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   732
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   733
        if self._names:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   734
            try:
51447
40943970b7ae config: move the option to mmap rev branch cache in the storage section
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 51375
diff changeset
   735
                if repo.ui.configbool(b'storage', b'revbranchcache.mmap'):
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   736
                    with repo.cachevfs(_rbcrevs) as fp:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   737
                        data = util.buffer(util.mmapread(fp))
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   738
                else:
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   739
                    data = repo.cachevfs.read(_rbcrevs)
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   740
                self._rbcrevs = rbcrevs(data)
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25266
diff changeset
   741
            except (IOError, OSError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   742
                repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   743
                    b"couldn't read revision branch cache: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   744
                    % stringutil.forcebytestr(inst)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   745
                )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   746
        # remember number of good records on disk
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   747
        self._rbcrevslen = min(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   748
            len(self._rbcrevs) // _rbcrecsize, len(repo.changelog)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   749
        )
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   750
        if self._rbcrevslen == 0:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   751
            self._names = []
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   752
        self._rbcnamescount = len(self._names)  # number of names read at
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   753
        # _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   754
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   755
    def _clear(self):
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   756
        self._rbcsnameslen = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   757
        del self._names[:]
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   758
        self._rbcnamescount = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   759
        self._rbcrevslen = len(self._repo.changelog)
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   760
        self._rbcrevs = rbcrevs(bytearray(self._rbcrevslen * _rbcrecsize))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   761
        util.clearcachedproperty(self, b'_namesreverse')
40710
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   762
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   763
    @util.propertycache
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   764
    def _namesreverse(self):
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 44306
diff changeset
   765
        return {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
   766
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   767
    def branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   768
        """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
   769
        persistent cache."""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   770
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   771
        rbcrevidx = rev * _rbcrecsize
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   772
25266
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   773
        # 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
   774
        if rev == nullrev:
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   775
            return changelog.branchinfo(rev)
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   776
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
   777
        # 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
   778
        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
   779
            return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   780
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   781
        # 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
   782
        reponode = changelog.node(rev)[:_rbcnodelen]
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   783
        cachenode, branchidx = self._rbcrevs.unpack_record(rbcrevidx)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   784
        close = bool(branchidx & _rbccloseflag)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   785
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   786
            branchidx &= _rbcbranchidxmask
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   787
        if cachenode == b'\0\0\0\0':
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   788
            pass
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   789
        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
   790
            try:
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   791
                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
   792
            except IndexError:
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   793
                # recover from invalid reference to unknown branch
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   794
                self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   795
                    b"referenced branch names not found"
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   796
                    b" - rebuilding revision branch cache from scratch\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   797
                )
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   798
                self._clear()
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   799
        else:
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   800
            # rev/node map has changed, invalidate the cache from here up
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   801
            self._repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   802
                b"history modification detected - truncating "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   803
                b"revision branch cache to revision %d\n" % rev
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   804
            )
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   805
            truncate = rbcrevidx + _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   806
            self._rbcrevs.truncate(truncate)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   807
            self._rbcrevslen = min(self._rbcrevslen, truncate)
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   808
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   809
        # 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
   810
        return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   811
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   812
    def _branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   813
        """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
   814
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   815
        b, close = changelog.branchinfo(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   816
        if b in self._namesreverse:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   817
            branchidx = self._namesreverse[b]
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   818
        else:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   819
            branchidx = len(self._names)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   820
            self._names.append(b)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   821
            self._namesreverse[b] = branchidx
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   822
        reponode = changelog.node(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   823
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   824
            branchidx |= _rbccloseflag
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   825
        self._setcachedata(rev, reponode, branchidx)
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
   826
        return b, close
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
   827
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
   828
    def setdata(self, rev, changelogrevision):
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   829
        """add new data information to the cache"""
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
   830
        branch, close = changelogrevision.branchinfo
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
   831
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   832
        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
   833
            branchidx = self._namesreverse[branch]
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   834
        else:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   835
            branchidx = len(self._names)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   836
            self._names.append(branch)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   837
            self._namesreverse[branch] = branchidx
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   838
        if close:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   839
            branchidx |= _rbccloseflag
46372
3e91d9978bec branchmap: update rev-branch-cache incrementally
Joerg Sonnenberger <joerg@bec.de>
parents: 46360
diff changeset
   840
        self._setcachedata(rev, self._repo.changelog.node(rev), branchidx)
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   841
        # 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
   842
        # 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
   843
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   844
        #   self.branchinfo = self._branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   845
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   846
        # Since we now have data in the cache, we need to drop this bypassing.
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43499
diff changeset
   847
        if '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
   848
            del self.branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   849
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   850
    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
   851
        """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
   852
        if rev == nullrev:
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
   853
            return
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   854
        rbcrevidx = rev * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   855
        self._rbcrevs.pack_into(rbcrevidx, node, branchidx)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   856
        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
   857
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   858
        tr = self._repo.currenttransaction()
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   859
        if tr:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   860
            tr.addfinalize(b'write-revbranchcache', self.write)
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   861
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   862
    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
   863
        """Save branch cache if it is dirty."""
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
   864
        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
   865
        wlock = None
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   866
        step = b''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   867
        try:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   868
            # write the new names
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
   869
            if self._rbcnamescount < len(self._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
   870
                wlock = repo.wlock(wait=False)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   871
                step = b' names'
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   872
                self._writenames(repo)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   873
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   874
            # write the new revs
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
   875
            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
   876
            if start != len(self._rbcrevs):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   877
                step = b''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   878
                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
   879
                    wlock = repo.wlock(wait=False)
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   880
                self._writerevs(repo, start)
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   881
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
   882
        except (IOError, OSError, error.Abort, error.LockError) as inst:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   883
            repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   884
                b"couldn't write revision branch cache%s: %s\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   885
                % (step, stringutil.forcebytestr(inst))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   886
            )
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   887
        finally:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   888
            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
   889
                wlock.release()
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   890
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   891
    def _writenames(self, repo):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   892
        """write the new branch names to revbranchcache"""
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   893
        if self._rbcnamescount != 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   894
            f = repo.cachevfs.open(_rbcnames, b'ab')
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   895
            if f.tell() == self._rbcsnameslen:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   896
                f.write(b'\0')
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   897
            else:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   898
                f.close()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   899
                repo.ui.debug(b"%s changed - rewriting it\n" % _rbcnames)
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   900
                self._rbcnamescount = 0
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   901
                self._rbcrevslen = 0
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   902
        if self._rbcnamescount == 0:
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   903
            # before rewriting names, make sure references are removed
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   904
            repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   905
            f = repo.cachevfs.open(_rbcnames, b'wb')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   906
        f.write(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   907
            b'\0'.join(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   908
                encoding.fromlocal(b)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   909
                for b in self._names[self._rbcnamescount :]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   910
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42603
diff changeset
   911
        )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   912
        self._rbcsnameslen = f.tell()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   913
        f.close()
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   914
        self._rbcnamescount = len(self._names)
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   915
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   916
    def _writerevs(self, repo, start):
47062
f38bf44e077f black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents: 46819
diff changeset
   917
        """write the new revs to revbranchcache"""
42185
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
   918
        revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   919
        with repo.cachevfs.open(_rbcrevs, b'ab') as f:
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   920
            if f.tell() != start:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   921
                repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   922
                    b"truncating cache/%s to %d\n" % (_rbcrevs, start)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   923
                )
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   924
                f.seek(start)
42185
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
   925
                if f.tell() != start:
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
   926
                    start = 0
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
   927
                    f.seek(start)
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
   928
                f.truncate()
ececa45c80d8 revbranchcache: use context manager in _writerevs() to write to file
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42184
diff changeset
   929
            end = revs * _rbcrecsize
51375
02e7d79edf62 branchmap: use mmap for faster revbranchcache loading
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51290
diff changeset
   930
            f.write(self._rbcrevs.slice(start, end))
42184
09fd338522fa revbranchcache: factor logic to write names and revs in separate functions
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42138
diff changeset
   931
        self._rbcrevslen = revs